package com.iocollege.tinyframe.common.exception;

import com.iocollege.tinyframe.common.core.AjaxResult;
import com.iocollege.tinyframe.common.core.constant.HttpStatus;
import com.iocollege.tinyframe.common.utils.MessageUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;

/**
 * 基础异常
 *
 * @author ruoyi
 */
public class BaseException extends RuntimeException
{
    private static final long serialVersionUID = 1L;

    /**
     * 所属模块
     */
    private String module;

    /**
     * 错误码
     */
    private String code;

    /**
     * 错误码对应的参数
     */
    private Object[] args;

    /**
     * 错误消息
     */
    private String defaultMessage;

    public BaseException(String module, String code, Object[] args, String defaultMessage)
    {
        this.module = module;
        this.code = code;
        this.args = args;
        this.defaultMessage = defaultMessage;
    }

    public BaseException(String module, String code, Object[] args)
    {
        this(module, code, args, null);
    }

    public BaseException(String module, String defaultMessage)
    {
        this(module, null, null, defaultMessage);
    }

    public BaseException(String code, Object[] args)
    {
        this(null, code, args, null);
    }

    public BaseException(String defaultMessage)
    {
        this(null, null, null, defaultMessage);
    }

    @Override
    public String getMessage()
    {
        String message = null;
        if (!StringUtils.isEmpty(code))
        {
            message = MessageUtils.message(code, args);
        }
        if (message == null)
        {
            message = defaultMessage;
        }
        return message;
    }

    public String getModule()
    {
        return module;
    }

    public String getCode()
    {
        return code;
    }

    public Object[] getArgs()
    {
        return args;
    }

    public String getDefaultMessage()
    {
        return defaultMessage;
    }

    /**
     * 全局异常处理器
     *
     * @author ruoyi
     */
    @RestControllerAdvice
    public static class GlobalExceptionHandler
    {
        private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);

        /**
         * 基础异常
         */
        @ExceptionHandler(BaseException.class)
        public AjaxResult baseException(BaseException e)
        {
            return AjaxResult.error(e.getMessage());
        }

        /**
         * 业务异常
         */
        @ExceptionHandler(CustomException.class)
        public AjaxResult businessException(CustomException e)
        {
            if (com.iocollege.tinyframe.common.utils.StringUtils.isNull(e.getCode()))
            {
                return AjaxResult.error(e.getMessage());
            }
            return AjaxResult.error(e.getCode(), e.getMessage());
        }

        @ExceptionHandler(NoHandlerFoundException.class)
        public AjaxResult handlerNoFoundException(Exception e)
        {
            log.error(e.getMessage(), e);
            return AjaxResult.error(HttpStatus.NOT_FOUND.getCode(), "路径不存在，请检查路径是否正确");
        }
    //
    //    @ExceptionHandler(AccessDeniedException.class)
    //    public AjaxResult handleAuthorizationException(AccessDeniedException e)
    //    {
    //        log.error(e.getMessage());
    //        return AjaxResult.error(HttpStatus.FORBIDDEN.getCode(), "没有权限，请联系管理员授权");
    //    }
    //
    //    @ExceptionHandler(AccountExpiredException.class)
    //    public AjaxResult handleAccountExpiredException(AccountExpiredException e)
    //    {
    //        log.error(e.getMessage(), e);
    //        return AjaxResult.error(e.getMessage());
    //    }
    //
    //    @ExceptionHandler(UsernameNotFoundException.class)
    //    public AjaxResult handleUsernameNotFoundException(UsernameNotFoundException e)
    //    {
    //        log.error(e.getMessage(), e);
    //        return AjaxResult.error(e.getMessage());
    //    }

        @ExceptionHandler(Exception.class)
        public AjaxResult handleException(Exception e)
        {
            log.error(e.getMessage(), e);
            return AjaxResult.error(e.getMessage());
        }

        /**
         * 自定义验证异常
         */
        @ExceptionHandler(BindException.class)
        public AjaxResult validatedBindException(BindException e)
        {
            log.error(e.getMessage(), e);
            String message = e.getAllErrors().get(0).getDefaultMessage();
            return AjaxResult.error(message);
        }

        /**
         * 自定义验证异常
         */
        @ExceptionHandler(MethodArgumentNotValidException.class)
        public Object validExceptionHandler(MethodArgumentNotValidException e)
        {
            log.error(e.getMessage(), e);
            String message = e.getBindingResult().getFieldError().getDefaultMessage();
            return AjaxResult.error(message);
        }


    }
}
